package com.bx.implatform.growUp.service.Impl;

import com.bx.implatform.growUp.entity.*;
import com.bx.implatform.growUp.mapper.DataDictionaryMapper;
import com.bx.implatform.growUp.mapper.DispatchMapper;
import com.bx.implatform.growUp.mapper.FloodMapper;
import com.bx.implatform.growUp.mapper.SnowMapper;
import com.bx.implatform.growUp.param.GetEventListParam;
import com.bx.implatform.growUp.param.GetEventTypeStatisticsParam;
import com.bx.implatform.growUp.service.DispatchService;
import com.bx.implatform.growUp.service.GrowUpApiService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class DispatchServiceImpl implements DispatchService {

    private final DispatchMapper dispatchMapper;
    private final FloodMapper floodMapper;
    private final DataDictionaryMapper dataDictionaryMapper;
    private final SnowMapper snowMapper;
    private final GrowUpApiService growUpApiService;
    ObjectMapper objectMapper = new ObjectMapper();
    private static final DateTimeFormatter DATE_TIME_FORMATTER =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 救援人员列表
     *
     * @param pageIndex
     * @param pageSize
     * @return
     */
    @Override
    public List<EmergencyUser> emergencyUserList(Integer pageIndex, Integer pageSize) {
        return dispatchMapper.emergencyUserList(pageIndex, pageSize);
    }

    /**
     * 获取事件数统计
     *
     * @return
     */
    @Override
    public Map<String, Map<String, Object>> eventCount() {
        Map<String, Map<String, Object>> resultMap = new HashMap<>();
        resultMap.put("总数", this.event("year", "", "", "", "year"));

        JsonNode json = growUpApiService.getEventTypeList();
        List<EventType> eventTypes = objectMapper.convertValue(json, new TypeReference<List<EventType>>() {
        });
        eventTypes.forEach(eventType -> {
            resultMap.put(eventType.getName(), this.event("year", eventType.getId(), "", "", "year"));
        });
        return resultMap;
    }

    /**
     * 获取今日事件
     *
     * @return
     */
    @Override
    public Map<String, Map<String, Object>> todayEventCount() {
        Map<String, Map<String, Object>> resultMap = new HashMap<>();

        JsonNode json = growUpApiService.getEventTypeList();
        List<EventType> eventTypes = objectMapper.convertValue(json, new TypeReference<List<EventType>>() {
        });
        // 获取当前日期时间
        LocalDateTime now = LocalDateTime.now();

        // 定义格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 格式化输出
        String formattedDateTime = now.format(formatter);
        eventTypes.forEach(eventType -> {
            resultMap.put(eventType.getName(), this.event("", eventType.getId(), formattedDateTime + " 00:00:00", "", "today"));
        });
        return resultMap;
    }

    /**
     * 获取事件类型占比
     *
     * @return
     */
    @Override
    public Map<String, Map<String, Object>> eventProportion() {
        Map<String, Map<String, Object>> map = this.eventCount();
        // 安全地获取总数，使用 Number 类型
        Number sumNumber = (Number) map.get("总数").get("thisYear");
        double sum = sumNumber != null ? sumNumber.doubleValue() : 0.0;
        map.forEach((key, value) -> {
            if (!("总数").equals(key)) {
                // 安全地获取当前类型的数量
                Number thisYearNumber = (Number) value.get("thisYear");
                double thisYear = thisYearNumber != null ? thisYearNumber.doubleValue() : 0.0;
                // 计算占比
                double ratio = sum != 0 ? Math.round(thisYear / sum * 10000.0) / 100.0 : 0.0;
                value.put("proportion", ratio);
            }
        });
        return map;
    }

    /**
     * 事件类型分析
     *
     * @param queryType
     * @return
     */
    @Override
    public Map<String, List<EventCount>> eventAnalyse(String queryType) {
        Map<String, List<EventCount>> resultMap = new HashMap<>();
        JsonNode json = growUpApiService.getEventTypeList();
        List<EventType> eventTypes = objectMapper.convertValue(json, new TypeReference<List<EventType>>() {
        });
        eventTypes.forEach(eventType -> {
            if ("year".equals(queryType)) {
                resultMap.put(eventType.getName(), this.eventMonth("month", eventType.getId(), "", ""));
            } else {
                resultMap.put(eventType.getName(), this.eventMonth("day", eventType.getId(), "", ""));
            }
        });

        return resultMap;
    }

    /**
     * 分公司事件处置效率排名
     *
     * @return
     */
    @Override
    public LinkedHashMap<String, Object> eventEfficiency() {
        // 长事件列表接口参数对象，使用自己的参数对象
        GetEventListParam baseParam = new GetEventListParam();
        baseParam.setPage(1);
        baseParam.setPageSize(10000);
        // 长大事件列表接口
        JsonNode jsonNode = growUpApiService.getEventList(baseParam, null);
        List<EventEfficiency> eventList = objectMapper.convertValue(jsonNode.get("datas"), new TypeReference<List<EventEfficiency>>() {
        });
        List<EventEfficiency> efficiencies = eventList.stream().filter(e -> StringUtils.isNotBlank(e.getEndTime())).toList();
        // 2. 按roadId分组并计算平均处置时长
        Map<String, Long> result = efficiencies.stream()
                .collect(Collectors.groupingBy(
                        EventEfficiency::getRoadId,
                        Collectors.collectingAndThen(
                                Collectors.toList(),
                                list -> {
                                    // 计算总处置时长（分钟）
                                    long totalMinutes = list.stream()
                                            .mapToLong(e -> calculateDurationMinutes(e.getAlarmTime(), e.getEndTime()))
                                            .sum();
                                    // 计算平均处置时长
                                    return totalMinutes / list.size();
                                }
                        )
                ));

        // 3. 按value（平均处置时长）排序
        return result.entrySet().stream()
                .sorted(Map.Entry.comparingByValue())
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldValue, newValue) -> oldValue,
                        LinkedHashMap::new
                ));
    }

    /**
     * 当期防汛、除雪
     *
     * @param queryType
     * @param type
     * @return
     */
    @Override
    public Map<String, Object> floodSnow(String queryType, String type) {
        List<DataDictionary> list = dataDictionaryMapper.dataMap();
        Map<String, List<DataDictionary>> group = list.stream()
                .collect(Collectors.groupingBy(DataDictionary::getType));
        if (!group.containsKey(queryType)) {
            return null;
        }
        if (!group.get(queryType).stream().map(DataDictionary::getValue).toList().contains(type)) {
            return null;
        }
        if ("flood".equals(queryType)) {
            return floodMapper.floodSnow(type).stream()
                    .collect(Collectors.toMap(
                            map -> (String) map.get("x"),
                            map -> map.get("y")
                    ));
        } else if ("snow".equals(queryType)) {
            return snowMapper.floodSnow(type).stream()
                    .collect(Collectors.toMap(
                            map -> (String) map.get("x"),
                            map -> map.get("y")
                    ));
        }
        return null;
    }

    /**
     * 计算两个时间点之间的分钟数
     */
    private long calculateDurationMinutes(String startTime, String endTime) {
        try {
            LocalDateTime start = LocalDateTime.parse(startTime, DATE_TIME_FORMATTER);
            LocalDateTime end = LocalDateTime.parse(endTime, DATE_TIME_FORMATTER);
            return Duration.between(start, end).toMinutes();
        } catch (Exception e) {
            // 处理时间解析错误，返回0或抛出异常取决于业务需求
            return 0L;
        }
    }

    public List<EventCount> eventMonth(String type, String eventType, String startDate, String endDate) {
        GetEventTypeStatisticsParam param = new GetEventTypeStatisticsParam();
        param.setType(type);
        param.setEventType(eventType);
        param.setStartDate(startDate);
        param.setEndDate(endDate);
        JsonNode jsonStr = growUpApiService.getEventTypeStatistics(param);
        List<EventCount> eventCounts = objectMapper.convertValue(jsonStr, new TypeReference<List<EventCount>>() {
        });
        // 筛选今年的事件
        return eventCounts.stream()
                .filter(eventCount -> {
                    if (eventCount.getItem() != null) {
                        return type.equals("month") ? eventCount.getItem().split("-")[0].equals(LocalDate.now().getYear() + "") :
                                eventCount.getItem().substring(0, eventCount.getItem().lastIndexOf("-")).equals(YearMonth.from(LocalDate.now()).toString());
                    }
                    return false;
                })
                .toList();
    }


    public Map<String, Object> event(String type, String eventType, String startDate, String endDate, String queryType) {
        HashMap<String, Object> resultMap = new HashMap<>();
        GetEventTypeStatisticsParam param = new GetEventTypeStatisticsParam();
        param.setType(type);
        param.setEventType(eventType);
        param.setStartDate(startDate);
        param.setEndDate(endDate);
        JsonNode jsonStr = growUpApiService.getEventTypeStatistics(param);
        List<EventCount> eventCounts = objectMapper.convertValue(jsonStr, new TypeReference<List<EventCount>>() {
        });

        // 筛选今年的事件
        List<EventCount> yearCollect = eventCounts.stream()
                .filter(eventCount -> eventCount.getItem() != null &&
                        eventCount.getItem().equals(LocalDate.now().getYear() + ""))
                .toList();
        List<EventCount> oldYearCollect = eventCounts.stream()
                .filter(eventCount -> eventCount.getItem() != null &&
                        eventCount.getItem().equals((LocalDate.now().getYear() - 1) + ""))
                .toList();

        // 计算今年事件总数
        int yearSum = yearCollect.stream()
                .mapToInt(EventCount::getCount)
                .sum();
        int oldYearSum = oldYearCollect.stream()
                .mapToInt(EventCount::getCount)
                .sum();

        // 计算环比增长率
        double ratio = 0.0;
        if (oldYearSum != 0) {
            ratio = ((double) (yearSum - oldYearSum) / oldYearSum) * 100;
        } else if (yearSum > 0) {
            // 去年为0，今年有数据，增长率为无穷大，可以设置为特殊值
            ratio = 100.0; // 或者其他表示大幅增长的值
        }

        if ("year".equals(queryType)) {
            resultMap.put("thisYear", yearSum);
            resultMap.put("lastYear", oldYearSum);
            resultMap.put("ratio", String.format("%.2f", ratio));
        } else if ("today".equals(queryType)) {
            resultMap.put("today", yearSum);
            resultMap.put("yesterday", oldYearSum);
            resultMap.put("ratio", String.format("%.2f", ratio));
        }
        return resultMap;
    }
}
